package com.woniuxy.sale.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.woniuxy.commons.entity.sale.ChooseProduceMsg;
import com.woniuxy.commons.entity.sale.Product;
import com.woniuxy.commons.entity.sale.dto.ProductDto;
import com.woniuxy.commons.enums.DictCodeEnum;
import com.woniuxy.commons.result.Result;
import com.woniuxy.commons.utils.PageUtils;
import com.woniuxy.commons.entity.sale.vo.sale.ProductVo;
import com.woniuxy.sale.config.DictConfig;
import com.woniuxy.sale.mapper.ProductDao;
import com.woniuxy.sale.service.ProductService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * <P> @Author: ideaAdmin
 * <P> TODO: Class
 * <P> TODO:
 * <P> Date: 2022/4/20:14:27
 * <P> Description:
 */
@Service
public class ProductServiceImpl implements ProductService {
    @Resource
    private ProductDao productDao;


    @Override
    public Result findProductByPage(Integer currentPage, Integer limit, ProductVo productVo) {
        PageHelper.startPage(currentPage, limit);
        List<Product> productList = productDao.findProductByPage(productVo);

        PageInfo<Product> of = PageInfo.of(productList);
        PageUtils pageUtils = new PageUtils(of);

        List<ProductDto> productDtos = new ArrayList<>();
        productList.stream()
                .forEach(product -> {
                    ProductDto productDto = new ProductDto();
                    BeanUtils.copyProperties(product, productDto);

                    setField(product, productDto, "condition", DictCodeEnum.CONDITION);


                    setField(product, productDto, "perGram",
                            Math.toIntExact(DictConfig.getDictOne(DictCodeEnum.WORKMANSHIP.getId(), product.getWorkmanship()).getId()));

                    setField(product, productDto, "region", DictCodeEnum.REGION);
                    setField(product, productDto, "productStatus", DictCodeEnum.PRODUCE_STATUS);

                    setField(product, productDto, "depository",
                            Objects.requireNonNull(DictCodeEnum.getDictCode
                                    (Math.toIntExact(DictConfig.getDictOne(DictCodeEnum.REGION.getId(),
                                            product.getRegion()).getId()))));

                    setField(product, productDto, "singleOrNormal", DictCodeEnum.ITEM_TYPE);
                    setField(product, productDto, "workmanship", DictCodeEnum.WORKMANSHIP);
                    setField(product, productDto, "productType", DictCodeEnum.CATEGORY);

                    productDtos.add(productDto);
                });

        pageUtils.setList(productDtos);
        return Result.ok(pageUtils);
    }

    @Override
    @Transactional
    public Result updateAmountById(List<ChooseProduceMsg> chooseProduceMsgs) {
        chooseProduceMsgs.forEach(chooseProduceMsg ->
                productDao.updateAmountById(chooseProduceMsg));

        return Result.ok();
    }

    public static <S, T> T setField(S source, T target, String field, DictCodeEnum codeEnum) {
    //TODO 先找到对应的数字 然后判断它的这个数字能不能再找到子类 如果不能,则去设置值 否则继续使用当前方法 找到没有子类的数字

        try {
            Field targetField = source.getClass().getDeclaredField(field);
            Field sourceField = target.getClass().getDeclaredField(field);

            targetField.setAccessible(true);
            sourceField.setAccessible(true);

            //TODO 输入对应状态的枚举 返回这个字典对应所有的值
            DictConfig.getDict((long) codeEnum.getId()).stream()
                    //TODO 过滤器 根据字典对象的value值和本身的值做对比 则返回true
                    .filter(dict -> {
                        try {
                            return dict.getValue().compareTo(Long.valueOf(targetField.get(source).toString())) == 0;
                        } catch (IllegalAccessException e) {
                            e.printStackTrace();
                            return false;
                        }
                    })
                    //TODO 取得List的第一个下标
                    .findFirst()
                    //TODO 如果当前对象不为空 那么则设置对应的值
                    .ifPresent(dict -> {
                        try {
                            sourceField.set(target, dict.getName());
                        } catch (IllegalAccessException e) {
                            e.printStackTrace();
                        }
                    });

        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }

        return target;
    }

    /**
     * <P>Author ideaAdmin
     * <P>TODO: 重载方法 直接输入id 然后封装
     * <P>Date 21:57 2022/4/20
     * <P>* @param source
    * @param target
    * @param field
    * @param codeEnum
     * <P>* @return T
     **/
    public static <S, T> T setField(S source, T target, String field, Integer codeEnum) {
        //TODO 先找到对应的数字 然后判断它的这个数字能不能再找到子类 如果不能,则去设置值 否则继续使用当前方法 找到没有子类的数字

        try {
            Field targetField = source.getClass().getDeclaredField(field);
            Field sourceField = target.getClass().getDeclaredField(field);

            targetField.setAccessible(true);
            sourceField.setAccessible(true);

            //TODO 输入对应状态的枚举 返回这个字典对应所有的值
            DictConfig.getDict((long) codeEnum).stream()
                    //TODO 过滤器 根据字典对象的value值和本身的值做对比 则返回true
                    .filter(dict -> {
                        try {
                            return dict.getValue().compareTo(Long.valueOf(targetField.get(source).toString())) == 0;
                        } catch (IllegalAccessException e) {
                            e.printStackTrace();
                            return false;
                        }
                    })
                    //TODO 取得List的第一个下标
                    .findFirst()
                    //TODO 如果当前对象不为空 那么则设置对应的值
                    .ifPresent(dict -> {
                        try {
                            sourceField.set(target, dict.getName());
                        } catch (IllegalAccessException e) {
                            e.printStackTrace();
                        }
                    });

        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }

        return target;
    }










}
